package com.cjack.frenchexcel.service;

import com.alibaba.fastjson.JSONObject;
import com.cjack.frenchexcel.config.CommonConfig;
import com.cjack.frenchexcel.config.ErrorCodeDefine;
import com.cjack.frenchexcel.config.PrivateConfig;
import com.cjack.frenchexcel.dao.*;
import com.cjack.frenchexcel.exception.BackUpDataExsitsException;
import com.cjack.frenchexcel.exception.CommonException;
import com.cjack.frenchexcel.model.*;
import com.cjack.frenchexcel.table.*;
import com.cjack.frenchexcel.util.FileUtils;
import com.cjack.frenchexcel.util.ModelUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by root on 10/5/19
 */
@Service
public class SystemRecordService {

    @Value("${file.upload.baseServerDir}")
    String baseServerDir;
    @Value("${file.upload.spelitor}")
    String spelitor;

    @Autowired
    private SystemRecordDao dao;
    @Autowired
    private ConsumerRecordDao consumerRecordDao;
    @Autowired
    private RechargeRecordDao rechargeRecordDao;
    @Autowired
    private UserAdminDao userAdminDao;
    @Autowired
    private GoodsDao goodsDao;

    public List< SystemRecordModel> list() throws CommonException {
        Sort sort = new Sort( Sort.Direction.DESC, "createTime");
        return ModelUtils.copyListModel( dao.findAll( sort), SystemRecordModel.class);
    }

    public void add( SystemRecordModel model) throws CommonException {
        SystemRecordTable table = ModelUtils.copySignModel( model, SystemRecordTable.class);
        dao.save( table);
    }

    public void del( String ids){
        List< SystemRecordTable> tables = new ArrayList<>();
        String[] idArr = ids.split( ",");
        for( String id : idArr){
            SystemRecordTable table = new SystemRecordTable();
            table.setId( Long.valueOf( id));
            tables.add( table);
        }
        dao.deleteInBatch( tables);
    }

    public String download( Long id){
        SystemRecordTable table = dao.findOne( id);

        return "";
    }

    /**
     * 备份数据
     * @throws CommonException
     */
    public void backUp( String name) throws CommonException {
        //先把要备份的数据查询出来
        List<ConsumerRecordModel> consumerRecordTables = ModelUtils.copyListModel( consumerRecordDao.findAll(), ConsumerRecordModel.class);
        List<RechargeRecordModel> rechargeRecordTables = ModelUtils.copyListModel( rechargeRecordDao.findAll(), RechargeRecordModel.class);
        List<AdminUserModel> adminUserTables = ModelUtils.copyListModel( userAdminDao.findByBesideCodeOrderByJobNumberAsc( PrivateConfig.SUPER_ADMIN_CODE), AdminUserModel.class);
        List<GoodsModel> goodsUserTable = ModelUtils.copyListModel( goodsDao.findAll(), GoodsModel.class);
        //将需要备份的对象保存到，各自的文件
        String filePath = getBackUpFilePath();

        //保存对象到文件
        writeObjectTofile( consumerRecordTables, filePath, CommonConfig.BACKUP_DATA_CONSUMER + CommonConfig.BACKUP_FILE_SUBFIX);
        writeObjectTofile( rechargeRecordTables, filePath, CommonConfig.BACKUP_DATA_RECHARGE + CommonConfig.BACKUP_FILE_SUBFIX);
        writeObjectTofile( adminUserTables, filePath, CommonConfig.BACKUP_DATA_USER + CommonConfig.BACKUP_FILE_SUBFIX);
        writeObjectTofile( goodsUserTable, filePath, CommonConfig.BACKUP_DATA_GOODS + CommonConfig.BACKUP_FILE_SUBFIX);

        SystemRecordTable table = new SystemRecordTable();
        table.setCreateTime( new Date());
        table.setUpdateTime( new Date());
        table.setFilePath( filePath);
        JSONObject backUpCount = new JSONObject();
        backUpCount.put( CommonConfig.BACKUP_DATA_CONSUMER, consumerRecordTables.size() + "条");
        backUpCount.put( CommonConfig.BACKUP_DATA_RECHARGE, rechargeRecordTables.size() + "条");
        backUpCount.put( CommonConfig.BACKUP_DATA_USER, adminUserTables.size() + "条");
        backUpCount.put( CommonConfig.BACKUP_DATA_GOODS, goodsUserTable.size() + "条");
        table.setBackUpCount( backUpCount.toJSONString());
        table.setName( name);
        dao.save( table);
    }

    /**
     * 清除系统 消费记录表、充值记录表、员工信息表、商品表的数据
     */
    public void redo(){
        consumerRecordDao.clearAll();
        rechargeRecordDao.clearAll();
        userAdminDao.clearAll( PrivateConfig.SUPER_ADMIN_CODE);
        goodsDao.clearAll();

    }

    /**
     * 从备份还原
     * @param id
     */
    public List< String> restore( Long id) throws CommonException, BackUpDataExsitsException {
        //还原之前，先清理数据
        //备份完成之后，清除数据
        consumerRecordDao.clearAll();
        rechargeRecordDao.clearAll();
        userAdminDao.clearAll( PrivateConfig.SUPER_ADMIN_CODE);
        goodsDao.clearAll();

        List< String> results = new ArrayList<>();
        SystemRecordTable table = dao.getOne( id);
        String filePath = table.getFilePath();
        List<ConsumerRecordModel> consumerRecordModels = ( List<ConsumerRecordModel>)readObjectFromFile( filePath, CommonConfig.BACKUP_DATA_CONSUMER + CommonConfig.BACKUP_FILE_SUBFIX);
        List<RechargeRecordModel> rechargeRecordTables = ( List<RechargeRecordModel>)readObjectFromFile( filePath, CommonConfig.BACKUP_DATA_RECHARGE + CommonConfig.BACKUP_FILE_SUBFIX);
        List<AdminUserModel> adminUserTables = ( List<AdminUserModel>)readObjectFromFile( filePath, CommonConfig.BACKUP_DATA_USER + CommonConfig.BACKUP_FILE_SUBFIX);
        List<GoodsModel> goodsTables = ( List<GoodsModel>)readObjectFromFile( filePath, CommonConfig.BACKUP_DATA_GOODS + CommonConfig.BACKUP_FILE_SUBFIX);

        if( consumerRecordModels != null && consumerRecordModels.size() != 0){
            for( ConsumerRecordModel consumerRecordModel : consumerRecordModels){
                consumerRecordDao.restoreData( ModelUtils.copySignModel( consumerRecordModel, ConsumerRecordTable.class));
            }
        }
        if( rechargeRecordTables != null && rechargeRecordTables.size() != 0){
            for( RechargeRecordModel rechargeRecordModel : rechargeRecordTables){
                rechargeRecordDao.restoreData( ModelUtils.copySignModel( rechargeRecordModel, RechargeRecordTable.class));
            }
        }
        if( adminUserTables != null && adminUserTables.size() != 0){
            for( AdminUserModel adminUserModel : adminUserTables){
                adminUserModel.setRoleId( adminUserModel.getRole().getId());
                userAdminDao.restoreData( ModelUtils.copySignModel( adminUserModel, AdminUserTable.class));
            }
        }
        if( goodsTables != null && goodsTables.size() != 0){
            for( GoodsModel goodsModel : goodsTables){
                goodsDao.save( ModelUtils.copySignModel( goodsModel, GoodsTable.class));
            }
        }
        return results;
    }

    //备份文件路径，才有年月日+随机数的方式生成
    private String getBackUpFilePath(){
        String path = baseServerDir + CommonConfig.BACKUP_FILEPATH + spelitor + FileUtils.getDirByDate() + spelitor + FileUtils.getRandomPath();
        return path;
    }

    private void writeObjectTofile( Object content, String filePath, String fileName) throws CommonException {
        File dir = new File( filePath);
        if ( !dir.exists()) {
            dir.mkdirs();
        }
        File file = new File( filePath  + spelitor + fileName);
        OutputStream out;
        try {
            out = new FileOutputStream( file);
            ObjectOutputStream objOut = new ObjectOutputStream(out);
            objOut.writeObject( content);
            objOut.flush();
            objOut.close();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new CommonException( ErrorCodeDefine.INTERFACE_COMMON_ERROR, "数据备份失败");
        } catch (IOException e) {
            e.printStackTrace();
            throw new CommonException( ErrorCodeDefine.INTERFACE_COMMON_ERROR, "数据备份失败");
        }
    }

    /**
     * 从文件路径中读取文件
     * @param filePath
     * @return
     */
    private Object readObjectFromFile( String filePath, String fileName){
        try {
            ObjectInputStream is = new ObjectInputStream( new FileInputStream( filePath + spelitor + fileName));
            Object o = is.readObject();
            is.close();
            return o;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
}
